package ute.mvc.dao;

import java.util.ArrayList;
import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.FetchMode;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import ute.mvc.model.MyClass;
import ute.mvc.model.OpenCourse;
import ute.mvc.model.Subject;
import ute.mvc.model.User;

@Repository("openCourseDAO")
public class OpenCourseDAOImpl implements OpenCourseDAO {
	@Autowired
	SessionFactory sessionFactory;

	@SuppressWarnings("unchecked")
	public List<OpenCourse> getAllOpenCourse() {

		return sessionFactory.getCurrentSession()
				.createCriteria(OpenCourse.class).list();
	}

	@SuppressWarnings("unchecked")
	public List<OpenCourse> findOpenCourseById(String openCourseID) {

		return sessionFactory
				.getCurrentSession()
				.createCriteria(OpenCourse.class)
				.add(Restrictions
						.like("openCourseID", "%" + openCourseID + "%"))
				.setFetchMode("listLecturer", FetchMode.EAGER).list();
	}

	public void addOpenCourse(OpenCourse openCourse) {
		sessionFactory.getCurrentSession().save(openCourse);
	}

	public void updateOpenCourse(OpenCourse openCourse) {
		sessionFactory.getCurrentSession().merge(openCourse);
	}

	public void deleteOpenCourse(OpenCourse openCourse) {
		sessionFactory.getCurrentSession().delete(openCourse);
	}

	@SuppressWarnings("deprecation")
	public OpenCourse getOpenCourseById(String openCourseId) {

		return (OpenCourse) sessionFactory.getCurrentSession()
				.createCriteria(OpenCourse.class)
				.add(Restrictions.eq("openCourseId", openCourseId))
				.setFetchMode("listClass", FetchMode.EAGER).uniqueResult();
	}

	@SuppressWarnings("unchecked")
	public List<Subject> getSubjectByOpenCourseId(String openCourseId) {

		return sessionFactory.getCurrentSession().createCriteria(Subject.class)
				.createCriteria("listCourse_Subject")
				.createCriteria("openCourse")
				.add(Restrictions.eq("openCourseId", openCourseId)).list();
	}

	@SuppressWarnings("unchecked")
	public List<User> getLecturerByOpenCourseId(String openCourseId) {

		return sessionFactory.getCurrentSession().createCriteria(User.class)
				.createCriteria("listOpenCourse")
				.add(Restrictions.eq("openCourseId", openCourseId)).list();
	}

	public OpenCourse getOpenCourseByIdWithListLecturer(String openCourseId) {
		return (OpenCourse) sessionFactory.getCurrentSession()
				.createCriteria(OpenCourse.class)
				.add(Restrictions.eq("openCourseId", openCourseId))
				.setFetchMode("listLecturer", FetchMode.EAGER).uniqueResult();
	}

	@SuppressWarnings("unchecked")
	public List<MyClass> getAllClass(String openCourseId) {
		// TODO Auto-generated method stub
		return sessionFactory.getCurrentSession().createCriteria(MyClass.class)

		.add(Restrictions.eq("openCourse.openCourseId", openCourseId)).list();
	}

	public List<OpenCourse> getOpenCourseByStudent(User student) {
		// TODO Auto-generated method stub
		List<MyClass> lstClass = new ArrayList<MyClass>();
		lstClass.addAll(student.getListClass());
		List<OpenCourse> lstOpenCourse = new ArrayList<OpenCourse>();
		for (MyClass c : lstClass) {
			lstOpenCourse.add(c.getOpenCourse());
		}
		return lstOpenCourse;
	}

	@SuppressWarnings("unchecked")
	public List<Subject> getListAddSubjectByOpenCourseId(String openCourseId) {
		Session session = sessionFactory.getCurrentSession();
		List<String> subjectIds = session.createCriteria(Subject.class)
				.setProjection(Projections.property("subjectId"))
				.createCriteria("listCourse_Subject")
				.createCriteria("openCourse")
				.add(Restrictions.eq("openCourseId", openCourseId))
				.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY).list();

		if (subjectIds.size() != 0)
			return session
					.createCriteria(Subject.class)
					.add(Restrictions.not(Restrictions.in("subjectId",
							subjectIds))).list();
		else
			return session.createCriteria(Subject.class).list();
	}

	@SuppressWarnings({ "unchecked" })
	public List<User> getListAddLecturerByOpenCourseId(String openCourseId) {
		Session session = sessionFactory.getCurrentSession();

		List<String> lecturerIds = session.createCriteria(User.class)
				.setProjection(Projections.property("userId"))
				.createCriteria("listOpenCourse")
				.add(Restrictions.eq("openCourseId", openCourseId)).list();
		if (lecturerIds.size() != 0)
			return session
					.createCriteria(User.class)
					.add(Restrictions.not(Restrictions
							.in("userId", lecturerIds)))
					.add(Restrictions.eq("role", 2)).list();
		else
			return session.createCriteria(User.class)
					.add(Restrictions.eq("role", 2)).list();
	}

	public MyClass getClass(User student, OpenCourse oCourse) {
		// TODO Auto-generated method stub
		List<MyClass> listClass = new ArrayList<MyClass>();
		listClass.addAll(student.getListClass());
		for(MyClass c: listClass){
			if(c.getOpenCourse().getOpenCourseId().equals(oCourse.getOpenCourseId()))
				return c;
		}
		return null;
	}
}
